package com.example.jjwt_demo;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.text.SimpleDateFormat;
import java.util.Date;

@SpringBootTest
public class JjwtDemoApplicationTests {

    //创建token
    @Test
    public void testCreateToken() {
        //创建jwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                //声明的表示{"jti": "8888"}
                .setId("8888")
                //主题, 用户{"sub", "Rose"}
                .setSubject("Rose")
                //创建日{"ita": "xxxxxx"}
                .setIssuedAt(new Date())
                //第一个参数是算法, 第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "xxxx");

        //获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("##############");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //签名是无法解密的
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    //解析token
    @Test
    public void testParseToken(){
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0NDQwMjg1Mn0.2S9kZOhM9I4QfcVLujzaxhpKnIKdBy86MkvJbnNlb_E";
        //解析token 获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();

        System.out.println(claims);
        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issuedAt: " + claims.getIssuedAt());
    }

    //获取带有失效时间的token
    @Test
    public void testCreateTokenHasExp(){
        //当前系统时间
        long now = System.currentTimeMillis();
        long exp = now + 60 * 1000;  //设置过期一分钟

        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("8888")
                .setSubject("Rose")
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, "xxxx")
                //设置失效时间
                .setExpiration(new Date(exp));

        String token = jwtBuilder.compact();
        System.out.println(token);
    }

    @Test
    public void testParseTokenHasExp(){
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0NDQxNzE5OCwiZXhwIjoxNjQ0NDE3MjU4fQ.jR0bjuurTlmPTIAAQw5FxhlYCA_ghjIK9VblFMZL-Tc";
        Claims claims = Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();

        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issuedAt: " + claims.getIssuedAt());

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("签发时间: " + simpleDateFormat.format(claims.getIssuedAt()));
        System.out.println("过期时间: " + simpleDateFormat.format(claims.getExpiration()));
        System.out.println("当前时间: " + simpleDateFormat.format(new Date()));
    }

    //创建token (自定义声明)
    @Test
    public void testCreateTokenByClaims() {
        //创建jwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                //声明的表示{"jti": "8888"}
                .setId("8888")
                //主题, 用户{"sub", "Rose"}
                .setSubject("Rose")
                //创建日{"ita": "xxxxxx"}
                .setIssuedAt(new Date())
                //第一个参数是算法, 第二个参数是盐
                .signWith(SignatureAlgorithm.HS256, "xxxx")
                //自定义声明  key value形式
                .claim("roles", "admin")
                //可以定义多个
                .claim("logo", "xxx.jpg");
                //还可以直接传入map
                //.addClaims();

        //获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("##############");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //签名是无法解密的
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    //解析token  (自定义声明)
    @Test
    public void testParseTokenByClaims(){
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0NDQ2MDQ1NSwicm9sZXMiOiJhZG1pbiIsImxvZ28iOiJ4eHguanBnIn0.4BfJxir8VL0z2s0m8EaIrtg6UJt11pxi92yrCg0JVZc";
        //解析token 获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("xxxx")
                .parseClaimsJws(token)
                .getBody();

        System.out.println(claims);
        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issuedAt: " + claims.getIssuedAt());
        System.out.println("roles: "+  claims.get("roles"));
        System.out.println("logo: "+  claims.get("logo"));
    }
}
